package dai.samples.histograms;

import com.codahale.metrics.*;
import dai.samples.metrics.HistogramsTest;
import dai.samples.metrics.MetricBase;

import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * @author daify
 * @date 2022-05-07
 */
public class ReservoirTest extends MetricBase {

    public static Random random = new Random();

    /**
     * ExponentiallyDecayingReservoir，它的大小没有限制，因此使用它对高频过程进行采样可能需要大量内存。因为它记录了每次测量
     * 基于指数级别的抽样算法，根据更新时间与开始时间的差值转化为权重值，权重越大数据被保留的几率越大。 内部使用ConcurrentSkipListMap并发跳表来存储数据
     * @param args
     * @throws InterruptedException
     */
    public static void main10(String[] args) throws InterruptedException {
        initMetric();
        // ExponentiallyDecayingReservoir(指数采样)
        // 注册一个Histogram
        Histogram histogram = new Histogram(new ExponentiallyDecayingReservoir());
        registry.register(MetricRegistry.name(HistogramsTest.class, "request", "histogram"), histogram);
        while(true){
            Thread.sleep(1000);
            histogram.update(random.nextInt(100000));
        }
    }

    /**
     * 随机抽样，随着更新次数的增加，数据被抽样的几率减少。
     * @param args
     * @throws InterruptedException
     */
    public static void main2(String[] args) throws InterruptedException {
        initMetric();
        // UniformReservoir(随机采样)
        // 注册一个Histogram
        Histogram histogram = new Histogram(new UniformReservoir());
        registry.register(MetricRegistry.name(HistogramsTest.class, "request", "histogram"), histogram);
        while(true){
            Thread.sleep(1000);
            histogram.update(random.nextInt(100000));
        }
    }

    /**
     * 只采集最近指定条数的数据
     * @param args
     * @throws InterruptedException
     */
    public static void main44(String[] args) throws InterruptedException {
        initMetric();
        // SlidingWindowReservoir(只存最近N条数据)
        // 注册一个Histogram
        Histogram histogram = new Histogram(new SlidingWindowReservoir(10));
        registry.register(MetricRegistry.name(HistogramsTest.class, "request", "histogram"), histogram);
        int i = 0;
        while(true){
            Thread.sleep(1000);
            i++;
            System.out.println(((i/10) + 1) * 100000);
            histogram.update(((i/10) + 1) * 100000);
        }
    }


    /**
     * 只采集过去指定时间段的数据
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        initMetric();
        // SlidingTimeWindowReservoir(指定时间窗口重置数据)
        // 注册一个Histogram
        Histogram histogram = new Histogram(new SlidingTimeWindowReservoir(10,TimeUnit.SECONDS));
        registry.register(MetricRegistry.name(HistogramsTest.class, "request", "histogram"), histogram);
        int i = 0;
        while(true){
            Thread.sleep(1000);
            i++;
            System.out.println(((i/10) + 1) * 100000);
            histogram.update(((i/10) + 1) * 100000);
        }
    }

    /**
     * 只采集过去指定时间段的数据
     * GC开销比SlidingTimeWindow低60-80倍
     * 10 K测量/秒，存储时间为1分钟，将需要10000*60*128/8=9600000字节~9兆字节
     * @param args
     * @throws InterruptedException
     */
    public static void main32(String[] args) throws InterruptedException {
        initMetric();
        // SlidingTimeWindowReservoir(指定时间窗口重置数据)
        // 注册一个Histogram
        Histogram histogram = new Histogram(new SlidingTimeWindowArrayReservoir(30,TimeUnit.SECONDS));
        registry.register(MetricRegistry.name(HistogramsTest.class, "request", "histogram"), histogram);

        for (int i = 0; i < 30; i++) {
            while(true){
                Thread.sleep(1000);
                histogram.update(random.nextInt(1000));
            }


        }

    }
}

